package com.jdk8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import org.junit.Test;

public class Lamda {

	public static void main(String[] args) {
	}

	@Test
	public void testFilter() {
		// filter ：筛选元素，将符合条件的元素保留，不符合条件的元素剔除
		List<Integer> list = new ArrayList<>(10);
		for (int i = 0; i < 10; i++) {
			list.add(i);
		}
		Stream<Integer> s = list.stream().filter(e -> e > 5);
		s.forEach(System.out::print);// 6789
		
		Integer i1 = new Integer(1),i2 = new Integer(1);
		System.out.println(i1.equals(i2));
	}

	@Test
	public void test() {

		// 1.多线程======================================================
		// Java 8之前：
		new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("Before Java8, too much code for too little to do");
			}
		}).start();

		// Java 8方式：
		new Thread(() -> System.out.println("In Java8, Lambda expression rocks !!")).start();

		// 2.集合======================================================
		List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
		// Java 8之前：
		System.out.println("Java 8之前");
		for (String feature : features) {
			System.out.println(feature);
		}

		// Java 8之后：
		System.out.println("Java 8之后");
		features.forEach(n -> System.out.println(n));

		// 使用Java 8的方法引用更方便，方法引用由::双冒号操作符标示，
		// 看起来像C++的作用域解析运算符
		System.out.println("Java 8方法引用");
		features.forEach(System.out::println);

		Collections.sort(features, (s1, s2) -> {
			return s1.compareTo(s2);
		});
		System.out.println("Java 8 Collections排序");
		features.forEach(System.out::println);
	}

	@Test
	public void testOperation() {
		/*
		 * 
		 * 1.不需要参数,返回值为5 () -> 5
		 * 
		 * 2.接收一个参数(数字类型),返回其2倍的值 x -> 2 * x
		 * 
		 * 3.接收2个参数(数字类型),返回他们的差值 (x,y) -> x - y
		 * 
		 * 4.接收2个int型整数,返回他们的和 (int x, int y) -> x + y
		 * 
		 * 5.接收一个String对象,并在控制台打印,不返回任何值(返回void) (String s) -> System.out.print(s)
		 * 
		 * 6.接收2个参数(数字类型),第1个数字加1,第2个数字加2,再求积 (int x, int y) -> { x += 1; y += 2; return
		 * x * y }
		 * 
		 */

		/*
		 * 
		 * MathOperation接口有且只有一个抽象方法operation时, 可以使用 MathOperation addition = (int a,
		 * int b) -> a + b; addition为实现了接口的一个对象, (int a, int b) -> a +
		 * b;作为一个函数实现了MathOperation的抽象方法operation; 当MathOperation接口存在两个抽象方法时;
		 * MathOperation addition = (int a, int b) -> a + b;在编写时报错;
		 * 
		 */

		// 7及以前
		MathOperation i = new MathOperation() {
			public int operation(int a, int b) {
				return a + b;
			}
		};

		i.operation(1, 2);

		// 8
		// 类型声明
		MathOperation addition = (int a, int b) -> a + b;
		System.out.println(addition.operation(1, 2));

		// 不用类型声明
		MathOperation subtraction = (a, b) -> a - b;

		// 大括号中的返回语句
		MathOperation multiplication = (int a, int b) -> {
			return a * b;
		};

		// 没有大括号及返回语句
		MathOperation division = (int a, int b) -> a / b;

		System.out.println("10 + 5 = " + operate(10, 5, addition));
		System.out.println("10 - 5 = " + operate(10, 5, subtraction));
		System.out.println("10 x 5 = " + operate(10, 5, multiplication));
		System.out.println("10 / 5 = " + operate(10, 5, division));

		System.out.println("6 / 3 = " + operate(6, 3, (int a, int b) -> a / b));

		// 输出结果,无返回值
		GreetingService greetService = (String message) -> System.out.println("hello " + message);
		greetService.sayMessage("world");
	}

	interface MathOperation {
		int operation(int a, int b);

		// int operation2(int a, int b);
		default int operation3(int a, int b) {
			return a + b;
		}
	}

	interface GreetingService {
		void sayMessage(String message);
	}

	private int operate(int a, int b, MathOperation mathOperation) {
		return mathOperation.operation(a, b);
	}
}